package org.onionframework.persistence.service;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.onionframework.persistence.model.Model;
import org.onionframework.persistence.query.OnionQuery;

/**
 * 通用业务类
 * 
 * 注意对于分页，这个接口中没有定义返回Page对象的方法
 * 
 * 因为对于不同的视图技术，可能要求的Page对象结构不同 对于JSF，分页包装在Core-JSF项目中，对于Struts等技术
 * 要求的分页方式，在Core-Page项目中，他们都扩展了本接口
 * 
 * @author Yang XuePing
 * @author allan zhasng
 */
public interface GenericService<T extends Model<? extends Serializable>> {

	/**
	 * @return 当前管理的实体类型
	 */
	Class<T> getEntityClass();

	/**
	 * 创建当前实体类型的对象
	 * 
	 * 把实体创建过程封装起来，可能可以使用AOP做一些通用的事情 例如在authentication项目中，在create上加AOP，判断如果
	 * 实体类实现了UserCreated接口，那么设置创建用户为当前用户
	 * 
	 * @return 新的对象
	 */
	T create();

	/**
	 * 保存
	 * 
	 * @param t
	 */
	void save(T t);

	/**
	 * 批量保存
	 * 
	 * @param objects
	 */
	void saveAll(Collection<T> objects);

	/**
	 * 删除
	 * 
	 * @param id
	 */
	void removeById(Serializable id);

	/**
	 * 删除
	 * 
	 * @param o
	 */
	void remove(T o);

	/**
	 * 刷新
	 * 
	 * @param o
	 */
	void refresh(Object o);

	void evict(Object o);

	void flush();

	void initProxy(Object o);

	void merge(Object o);

	/**
	 * 根据标识查询
	 * 
	 * @param id
	 *            实体标识
	 */
	T get(Serializable id);

	/**
	 * 加载对象，请google hibernate get和load的区别
	 * 
	 * @param id
	 *            对象标识
	 * @return 对象代理
	 */
	T load(Serializable id);

	/**
	 * 根据PropertyFilter查询总数
	 * 
	 * @param query
	 *            查询条件
	 * @return 记录总数
	 */
	Long count(OnionQuery query);

	List<T> findAll();

	/**
	 * 分页查询
	 * 
	 * @param query
	 *            查询条件
	 * @param start
	 *            起始记录序号
	 * @param maxResults
	 *            最大结果数
	 * @return 结果集合
	 */
	List<T> find(OnionQuery query);

	<E> List<E> findList(OnionQuery query);

	/**
	 * 根据属性名和属性值查询实体
	 * 
	 * @param name
	 *            属性名
	 * @param value
	 *            属性值
	 * @return 查询结果集合
	 */
	List<T> find(String name, Object value);

	/**
	 * 查询单一结果
	 */
	T findUnique(String name, Object value);

	/**
	 * 查询单一结果
	 */
	T findUnique(OnionQuery query);
}
